package com.yc.reflect;

import lombok.AllArgsConstructor;
import lombok.Data;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * Company 源辰信息
 *
 * @author navy
 * @date 2024/7/30
 * Email haijunzhou@hnit.edu.cn
 */
public class Demo2 {
}

@Data
class Person {
    String name;
    Address address;
    Person father;
    Person mather;
    List<Person> friends;

    public Person(String name) {
        this.name = name;
    }
    String say(String msg){
        return name + "说:" + msg;
    }
    static Person createZhangSan(){
        Person zhangsan = new Person("张三");
        zhangsan.father = new Person("张三丰");
        zhangsan.mather = new Person("李四");
        zhangsan.address = new Address("湖南","衡阳","工学院xxxx");
        zhangsan.friends = new ArrayList<>();
        zhangsan.friends.add(new Person("王五"));
        zhangsan.friends.add(new Person("赵六"));
        zhangsan.friends.add(new Person("刘七"));
        return zhangsan;
    }
    public static void test(){
        Person zhangSan = createZhangSan();
        System.out.println("getValue(zhangSan, \"name\") = " + getValue(zhangSan, "name"));
        System.out.println("getValue(zhangSan, \"mather.name\") = " + getValue(zhangSan, "mather.name"));
        System.out.println("getValue(zhangSan, \"father.name\") = " + getValue(zhangSan, "father.name"));
        System.out.println("getValue(zhangSan, \"address.city\") = " + getValue(zhangSan, "address.city"));
        // 扩展实现以下 2 个 ognl 语法
        System.out.println("getValue(zhangSan, \"friends[1].name\") = " + getValue(zhangSan, "friends[1].name"));
       // System.out.println("getValue(zhangSan, \"#father.say('你好中国')\") = " + getValue(zhangSan, "#father.say('你好中国')"));
    }
    public static void main(String[] args) {
        test();
    }
    public static Object getValue(Object object, String path) {
        try {
            if(path.contains(".") == false){
                if(path.contains("[")){
                    // 集合 或 数组
                    String snum = path.replaceAll("\\w+\\[(\\d+)\\].*", "$1");
                    int index = Integer.valueOf(snum);  // 获取下标
                    String prefix = path.replaceAll("(\\w+)\\[\\d+\\].*", "$1");
                    Object subObject =  getValue(object, prefix);
                    if(subObject.getClass().isArray()){
                        // 数组
                    } else if(List.class.isAssignableFrom(subObject.getClass())) {  // 判断继承关系
                        List list = (List) subObject;
                        Object listObject = list.get(index);
                        return listObject;
                    }
                } else {
                    // 使用反射实现当前方法
                    Field field = object.getClass().getDeclaredField(path);
                    field.setAccessible(true);
                    return field.get(object);
                }
            } else {
                int index = path.indexOf(".");
                String prefix = path.substring(0,index);
                String suffix = path.substring(index+1);
                Object subObject = getValue(object, prefix); // 递归调用
                return getValue(subObject, suffix); // 递归调用
            }



        }catch (Exception e){
            throw new RuntimeException(e);
        }

        return null;
    }
}
@Data
@AllArgsConstructor
class Address{
    String province;
    String city;
    String location;
}
